package org.wen.soft.util;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class FileUtil {

    /**
     * 获得文件名列表
     * @param dir     目录
     * @param endWith 后缀
     * @return        文件名称列表
     */
    public static List<String> listFile(String dir, String endWith) {
        Path path = Paths.get(dir);
        try (Stream<Path> walk = Files.walk(path)) {
            return walk.filter(Files::isRegularFile).map(Path::toString).filter(n -> n.endsWith(endWith)).collect(Collectors.toList());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获得java文件名列表
     */
    public static List<String> listJavaFile() {
        return listTargetFile(PropUtil::getJavaDir, ".java");
    }

    /**
     * 获得java Test文件名列表
     */
    public static List<String> listJavaTestFile() {
        return listTargetFile(PropUtil::getJavaTestDir, ".java");
    }

    /**
     * 获得class文件名列表
     */
    public static List<String> listClassFile() {
        return listTargetFile(PropUtil::getClassDir, ".class");
    }

    /**
     * 获得class Test文件名列表
     */
    public static List<String> listClassTestFile() {
        return listTargetFile(PropUtil::getClassTestDir, ".class");
    }


    /**
     * 获得不存在Test.java的class文件 （用于排除已存在单元测试类的类对应的class文件）
     */
    public static List<String> listClassNotExistsJavaTest() {
        List<String> files = new ArrayList<>();
        Set<String> modelPaths = PropUtil.getModelPaths();
        for (String modelPath : modelPaths) {

            String javaTestDir = PropUtil.getJavaTestDir(modelPath);
            String classDir = PropUtil.getClassDir(modelPath);

            List<String> testFiles = listFile(javaTestDir, ".java").stream().map(i -> i.replace(javaTestDir, "").replace("Test.java", "")).collect(Collectors.toList()) ;
            List<String> classFiles = listFile(classDir, ".class");
            // 排除
            for (String classFile : classFiles) {
                if (!testFiles.contains(classFile.replace(classDir, "").replace(".class", ""))) {
                    files.add(classFile);
                }
            }
        }
        return files;
    }


    private static List<String> listTargetFile(Function<String, String> targetDir, String endWith) {
        List<String> files = new ArrayList<>();
        Set<String> modelPaths = PropUtil.getModelPaths();
        for (String modelPath : modelPaths) {
            files.addAll(listFile(targetDir.apply(modelPath), endWith));
        }
        return files;
    }


    public static boolean exists(String file) {
        return Files.exists(Paths.get(file));
    }
}
